﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Engine;
using System.Windows.Threading;

namespace Demonstration
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class PresentationWindow : Window
    {
        private DemonstrationalEngine engine;
        /** timer that repeadly */
        private DispatcherTimer timer;
        /** holds lattice type variable. */
        private int latticeType;

        public PresentationWindow()
        {
            InitializeComponent();
            engine = new DemonstrationalEngine((int)Lattices.Square);
            ComboBoxItem squareItem = new ComboBoxItem();
            squareItem.Content = "квадратная";
            ComboBoxItem triangularItem = new ComboBoxItem();
            triangularItem.Content = "треугольная";
            selectLatticeComboBox.Items.Add(squareItem);
            selectLatticeComboBox.Items.Add(triangularItem);
            selectLatticeComboBox.SelectedIndex = 0;
        }

        /** draw this point on canvas */
        private void DrawPoint(Canvas canvas, Engine.Point point)
        {
            Ellipse ellipse = new Ellipse();
            ellipse.Height = 5;
            ellipse.Width = 5;
            ellipse.Fill = Brushes.Red;
            double height = canvas.ActualHeight;
            double width = canvas.ActualWidth;
            double left = (double)(point.X * width / engine.Xlenght);
            double bottom = (double)(point.Y * height / engine.Ylenght);
            ellipse.SetValue(Canvas.LeftProperty, left);
            ellipse.SetValue(Canvas.BottomProperty, bottom);
            ellipse.RenderTransform = new TranslateTransform(-2.5, 2.5);
            canvas.Children.Add(ellipse);
        }

        /** draw this bond on canvas. */
        private void DrawBond(Canvas canvas, Bond bond)
        {
            if (bond.StartPoint == null || bond.EndPoint == null) return;
            Line line = new Line();
            Engine.Point startPoint = bond.StartPoint;
            Engine.Point endPoint = bond.EndPoint;
            double height = canvas.ActualHeight;
            double width = canvas.ActualWidth;
            double left1 = (double)(startPoint.X * width / engine.Xlenght);
            double top1 = height - (double)(startPoint.Y * height / engine.Ylenght);
            double left2 = (double)(endPoint.X * width / engine.Xlenght);
            double top2 = height - (double)(endPoint.Y * height / engine.Ylenght);
            if (left1 < left2)
            {
                line.X1 = left1 + 2.5;
                line.X2 = left2 - 2.5;
            }
            else if (Math.Abs(left1 - left2) > 2)
            {
                line.X1 = left1 - 2.5;
                line.X2 = left2 + 2.5;
            }
            else
            {
                line.X1 = left1;
                line.X2 = left2;
            }
            if (top1 > top2)
            {
                line.Y1 = top1 - 2.5;
                line.Y2 = top2 + 2.5;
            }
            else if (Math.Abs(top2 - top1) > 2)
            {
                line.Y1 = top1 + 2.5;
                line.Y2 = top2 - 2.5;
            }
            else
            {
                line.Y1 = top1;
                line.Y2 = top2;
            }
            line.StrokeThickness = 1;
            line.Stroke = new SolidColorBrush(Colors.Green);
            canvas.Children.Add(line);
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            demoCanvas.Children.Clear();
            //then we render our engine to graphical interface.
            IList<Engine.Point> points = engine.Points;
            IList<Bond> bonds = engine.Bonds;
            foreach (Engine.Point point in points)
            {
                DrawPoint(demoCanvas, point);
            }
            foreach (Bond bond in bonds)
            {
                DrawBond(demoCanvas, bond);
            }
        }

        private void OnTimer(object s, EventArgs a)
        {
            DispatcherTimer timer = (DispatcherTimer)s;
            if (!engine.isConduct())
            {
                timer.Stop();
            }
            else
            {
                if (true == radioButton1.IsChecked)
                {
                    engine.CutPoint();
                }
                else if (true == radioButton2.IsChecked)
                {
                    engine.CutBond();
                }
                //then we refresh our table.
                Window_Loaded(null, null);
                bondLabel.Content = engine.BondIntegrityLevel.ToString();
                pointLabel.Content = engine.PointIntegrityLevel.ToString();
            }
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            if (timer == null)
            {
                timer = new DispatcherTimer();
                timer.Interval = new TimeSpan(500);
                timer.Tick += new EventHandler(OnTimer);
                timer.Start();
            }
            else if (!timer.IsEnabled)
            {
                timer.Start();
            }
        }

        private void button2_Click(object sender, RoutedEventArgs e)
        {
            if (timer != null)
            {
                timer.Stop();
            }
        }

        private void OnRefreshScreen(object sender, RoutedEventArgs e)
        {
            if(timer != null){
                timer.Stop();
            }
            engine = new DemonstrationalEngine(latticeType);
            Window_Loaded(null, null);
            bondLabel.Content = "- -";
            pointLabel.Content = "- -";
        }

        /** on change lattice type event */
        private void selectLatticeComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            int latticeType = ((ComboBox)sender).SelectedIndex;
            this.latticeType = latticeType;
            OnRefreshScreen(sender,e);
        }
    }
}
